iT邦幫忙

2026 iThome 鐵人賽

DAY 13
0
JavaScript

QA 的 JavaScript 初心之路:30 天做出一個能玩的戰鬥小遊戲《勇者 vs 小怪》系列 第 28 篇

Day28|沒學新東西的一天,卻發現了不少舊問題

  • 分享至 

  • xImage
  •  

今天的主題:收尾——把「能動」變成「能看」

功能到昨天就完整了:戰鬥、骰子、增益、紀錄、震動、勝負。但整個畫面還是很像一份作業。

今天做三件事:把樣式整理好、確認手機能玩、修掉自己玩出來的小問題。

第一件事:把顏色從程式碼裡抽出來

之前的 CSS 到處都是寫死的色碼。想調個顏色要先搜尋它出現在幾個地方,然後一個一個改 —— 而且一定會漏掉一兩個。

所以先做一件事:把所有顏色集中成變數。

:root {
  --bg:        #f4f1ea;
  --panel:     #ffffff;
  --ink:       #2b2b2b;
  --ink-soft:  #6b6b6b;
  --line:      #dcd7cc;
  --hero:      #4a8f4a;
  --enemy:     #a34242;
  --warn:      #e5ab22;
  --danger:    #d13b2e;
  --accent:    #2a6496;
  --hover:     #f0ece3;
}

然後所有地方改成 var(--hero) 這樣引用。

這叫 CSS 自訂屬性(custom properties),寫在 :root 裡就是全站通用。好處很直接:想換配色只要改這十個值,不用去翻兩百行 CSS。

這件事的本質跟 Day 27 把骰子數值抽成 DICE_FACES 一模一樣 —— 同一個值不要散落在很多地方。當時是為了讓遊戲和模擬器同步,今天是為了讓配色可以一次改完。

順帶一提,我原本以為這是「美化」的工作,做完才發現它更像整理:把「這裡要紅色」和「紅色是哪個紅」分開,前者寫在用的地方,後者集中管理。

第二件事:手機版

我用 @media 針對窄螢幕調整:

@media (max-width: 420px) {
  body { padding: 16px 12px 32px; }
  h1 { font-size: 23px; }

  /* 三顆按鈕平均分配寬度,而且加高到手指好按 */
  #controls button {
    flex: 1;
    padding: 12px 6px;
    font-size: 14px;
  }

  #log { height: 120px; font-size: 13px; }
}

@media (max-width: 420px) 的意思是「螢幕寬度在 420px 以下時,套用這些規則」。它不是給手機專用的 —— 把電腦瀏覽器的視窗拉窄也會生效,這也是最方便的測試方法。

三個調整的理由:

調整 為什麼
縮小外距 手機螢幕窄,留白太多內容就被擠扁
按鈕 flex: 1 + 加高 三顆按鈕平均分配整行,而且手指比滑鼠游標粗很多
紀錄區變矮 手機螢幕短,固定 150px 會把其他東西擠到看不見

實測的結果比我預期好:三顆按鈕沒有擠成兩行、輸入 10 個字的名字也不會把版面撐開、按鈕大小按起來很舒服。

名字不會撐開版面,是因為我在 CSS 加了這個:

.fighter-name { word-break: break-all; }

沒有這行的話,一串很長的英文或數字會被當成「一個不能斷的詞」,硬生生把整個區塊推寬。這是一個要主動預防、不然等使用者輸入怪東西才會發現的問題 —— 跟 Day 15 測輸入框是同一種思路。

第三件事:改掉我自己都沒注意到的習慣

整理 CSS 的時候,我發現自己把 button:hover 的底色寫死成 #f0ece3。單獨看沒問題,但它和 --panel、--line 其實是同一組配色的一部分,卻被排除在變數之外。

一組值裡漏掉一個,就等於沒有集中管理。 因為只要有一個例外,下次換配色的時候它就會留在原地,然後跟新的顏色打架。

所以我把它也抽成 --hover。這種「差一點點就完整」的東西,不去主動檢查就會一直留著。

順手也補了鍵盤操作的外框:

button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

:focus-visible 的特別之處是:用滑鼠點的時候不會出現外框,用鍵盤 Tab 過去才會。這樣既不會干擾滑鼠使用者,又讓鍵盤使用者知道現在焦點在哪裡。接續 Day 25 那個無障礙的話題,這是另一個成本很低但確實有人需要的細節。

收尾這天讓我重新想了一件事

前 27 天,每一天都有一個明確要學的東西:迴圈、函式、DOM、事件、亂數、非同步……今天沒有新語法,做的全是「把已經存在的東西整理好」。

一開始我覺得這天會很無聊,做完卻發現它比想像中有價值 —— 因為整理的過程會逼你重新看一遍所有決定。哪些顏色其實是同一個用途卻用了不同的值、哪些地方寫死了不該寫死的東西、哪些情況我從來沒測過(例如很窄的螢幕)。

這跟 Day 26 寫遊戲說明時的感覺很像:動筆整理的時候,才會發現自己沒想清楚的地方。

小結

今天搞懂的事:

  • CSS 自訂屬性(:root + var())把配色集中管理,換色只要改一個地方
  • 這跟 Day 27 抽出 DICE_FACES 是同一個原則:同一個值不要散落在很多地方
  • 一組值裡漏掉一個,就等於沒有集中管理
  • @media (max-width: 420px) 做窄螢幕調整;拉窄瀏覽器視窗就能測
  • 手機上按鈕要更大(手指比游標粗)、紀錄區要更矮(螢幕短)
  • word-break: break-all 防止長名字把版面撐開
  • :focus-visible 只在鍵盤操作時顯示外框,不干擾滑鼠使用者
  • 整理的過程會逼你重新檢視所有決定 —— 這天沒學新東西,但發現了不少舊問題

明天把它放到網路上,讓它有一個真正的網址。


上一篇
Day27|骰子與人性,賭性堅強與遊戲平衡
下一篇
Day29|上線之後,我的紀錄不見了
系列文
QA 的 JavaScript 初心之路:30 天做出一個能玩的戰鬥小遊戲《勇者 vs 小怪》 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言